/*
 * FileName MoonPixelBuffer.cpp
*/

#include "stdafx.h"
#include <string.h>
#include "MoonPixelBuffer.h"

namespace DeepZoomImage
{
	MoonPixbuf::MoonPixbuf()
	: m_IsPremultiplied(true)
	, m_BufWidth(0)
	, m_BufHeight(0)
	, m_RowStride(0)
	, m_NumChannels(0)
	, m_pPixelsBuf(NULL)
	, crc_error(false)
	, image_surface(NULL)
	{

	}

	MoonPixbuf::MoonPixbuf (cairo_surface_t *image_surface, bool crc_error)
	: m_IsPremultiplied(true)
	, m_BufWidth(0)
	, m_BufHeight(0)
	, m_RowStride(0)
	, m_NumChannels(0)
	, m_pPixelsBuf(NULL)	
	{
		this->image_surface = image_surface;
		this->crc_error = crc_error;
	}

	gint MoonPixbuf::GetWidth ()
	{
		if (crc_error)
			return 1;
		return cairo_image_surface_get_width (image_surface);
	}

	gint MoonPixbuf::GetHeight ()
	{
		if (crc_error)
			return 1;
		return cairo_image_surface_get_height (image_surface);
	}

	gint MoonPixbuf::GetRowStride () 
	{
		if (crc_error)
			return 4;
		return cairo_image_surface_get_stride (image_surface);
	}
	gint MoonPixbuf::GetNumChannels () 
	{
		if (crc_error)
			return 4;

		return 4;
	}

	guchar* MoonPixbuf::GetPixels () 
	{
		if (crc_error)
			return (guchar *) g_malloc0 (4);

		return cairo_image_surface_get_data (image_surface);
	}

	gboolean MoonPixbuf::IsPremultiplied () 
	{
		return m_IsPremultiplied;
	}

	MoonPixbuf::~MoonPixbuf () 
	{
		cairo_surface_destroy (image_surface);
		image_surface = NULL;
		if ( m_pPixelsBuf )
		{
			delete m_pPixelsBuf;
		}
	}

	MoonPixbufLoader::MoonPixbufLoader(const char* imageType)
	{
		crc_error = false;
		data = g_byte_array_new();
		image_type = imageType;
		offset = 0;
		pixbuf = NULL;
	}
	MoonPixbufLoader::MoonPixbufLoader()
	{
		crc_error = false;
		data = g_byte_array_new();
		image_type = "png";
        offset = 0;
		pixbuf = NULL;
	}

	void MoonPixbufLoader::Write (const guchar *buffer, int buflen/*, MoonError **error = NULL*/)
	{
		g_byte_array_append(data,buffer,buflen);
	}

	void MoonPixbufLoader::SetImageData(unsigned char* dataBuffer,int width,int height,int stride)
	{
		data_Buffer = dataBuffer;
		imageWidth = width;
		imageHeight = height;
		imageStride = stride;
	}
	void MoonPixbufLoader::Close() 
	{
	}

	MoonPixbuf* MoonPixbufLoader::GetPixbuf ()
	{
		if (pixbuf != NULL)
			return pixbuf;

		cairo_surface_t *image_surface = NULL;

		if (image_type == NULL || strcmp (image_type, "png") == 0) 
			image_surface = cairo_image_surface_create_from_png_stream (cairo_read_func, this);
		else
			//g_warning ("jpeg is currently unsupported");/***/
		   //image_surface = cairo_image_surface_create_for_data(data_Buffer,CAIRO_FORMAT_RGB24,imageWidth,imageHeight,imageWidth*4);
		
		image_surface = cairo_image_surface_create_for_data(data_Buffer,CAIRO_FORMAT_ARGB32,imageWidth,imageHeight,imageWidth*4);  // mem leak

		//g_warning ("MPLA::GetPixbuf-> after create");
		pixbuf = new MoonPixbuf (image_surface, false);   // mem leak
		return pixbuf;
	}

	cairo_status_t MoonPixbufLoader::ReadFunc (unsigned char *buffer, unsigned int len)
	{
		if (data->len < (offset + len))
			return CAIRO_STATUS_NO_MEMORY;

		memmove (buffer, data->data + offset, len);
		offset += len;

		return CAIRO_STATUS_SUCCESS;
	}

	cairo_status_t MoonPixbufLoader::cairo_read_func (void *closure, unsigned char *data, unsigned int len)
	{
		MoonPixbufLoader *loader = (MoonPixbufLoader *)closure;
		return loader->ReadFunc (data, len);
	}

	MoonPixbufLoader::~MoonPixbufLoader ()
	{
		g_byte_array_free(data,true);
		data = NULL;
	}
}
